// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include "QvisStatisticalTrendsWindow.h"

#include <StatisticalTrendsAttributes.h>

#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QButtonGroup>
#include <QRadioButton>
#include <QvisVariableButton.h>


// ****************************************************************************
// Method: QvisStatisticalTrendsWindow::QvisStatisticalTrendsWindow
//
// Purpose: 
//   Constructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisStatisticalTrendsWindow::QvisStatisticalTrendsWindow(const int type,
                         StatisticalTrendsAttributes *subj,
                         const QString &caption,
                         const QString &shortName,
                         QvisNotepadArea *notepad)
    : QvisOperatorWindow(type,subj, caption, shortName, notepad)
{
    atts = subj;
}


// ****************************************************************************
// Method: QvisStatisticalTrendsWindow::~QvisStatisticalTrendsWindow
//
// Purpose: 
//   Destructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisStatisticalTrendsWindow::~QvisStatisticalTrendsWindow()
{
}


// ****************************************************************************
// Method: QvisStatisticalTrendsWindow::CreateWindowContents
//
// Purpose: 
//   Creates the widgets for the window.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   Kathleen Biagas, Tue Apr 18 16:34:41 PDT 2023
//   Support Qt6: buttonClicked -> idClicked.
//
// ****************************************************************************

void
QvisStatisticalTrendsWindow::CreateWindowContents()
{
    QGridLayout *mainLayout = new QGridLayout(0);
    topLayout->addLayout(mainLayout);

    QGroupBox * timeGroup = new QGroupBox(central);
    timeGroup->setTitle(tr("Time Slices"));
    topLayout->addWidget(timeGroup);

    QGridLayout *timeLayout = new QGridLayout(timeGroup);
    timeLayout->setContentsMargins(5,5,5,5);
    timeLayout->setSpacing(10);

    // Start
    startTrendTypeLabel = new QLabel(tr("Type of sampling"), central);
    timeLayout->addWidget(startTrendTypeLabel,0,0);
    startTrendType = new QWidget(central);
    startTrendTypeButtonGroup= new QButtonGroup(startTrendType);
    QHBoxLayout *startTrendTypeLayout = new QHBoxLayout(startTrendType);
    startTrendTypeLayout->setContentsMargins(0,0,0,0);
    startTrendTypeLayout->setSpacing(10);

    QRadioButton *startTrendTypeTrendTypeEnumAbsolute = new QRadioButton(tr("Absolute"), startTrendType);
    startTrendTypeButtonGroup->addButton(startTrendTypeTrendTypeEnumAbsolute, 0);
    startTrendTypeLayout->addWidget(startTrendTypeTrendTypeEnumAbsolute);
    QRadioButton *startTrendTypeTrendTypeEnumRelative = new QRadioButton(tr("Relative"), startTrendType);
    startTrendTypeButtonGroup->addButton(startTrendTypeTrendTypeEnumRelative, 1);
    startTrendTypeLayout->addWidget(startTrendTypeTrendTypeEnumRelative);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(startTrendTypeButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(startTrendTypeChanged(int)));
#else
    connect(startTrendTypeButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(startTrendTypeChanged(int)));
#endif
    timeLayout->addWidget(startTrendType, 0,1);

    startIndexLabel = new QLabel(tr("Index of first time slice"), central);
    timeLayout->addWidget(startIndexLabel,1,0);
    startIndex = new QLineEdit(central);
    connect(startIndex, SIGNAL(returnPressed()),
            this, SLOT(startIndexProcessText()));
    timeLayout->addWidget(startIndex, 1,1);

    // Stop
    stopTrendTypeLabel = new QLabel(tr("Type of sampling"), central);
    timeLayout->addWidget(stopTrendTypeLabel,2,0);
    stopTrendType = new QWidget(central);
    stopTrendTypeButtonGroup= new QButtonGroup(stopTrendType);
    QHBoxLayout *stopTrendTypeLayout = new QHBoxLayout(stopTrendType);
    stopTrendTypeLayout->setContentsMargins(0,0,0,0);
    stopTrendTypeLayout->setSpacing(10);
    QRadioButton *stopTrendTypeTrendTypeEnumAbsolute = new QRadioButton(tr("Absolute"), stopTrendType);
    stopTrendTypeButtonGroup->addButton(stopTrendTypeTrendTypeEnumAbsolute, 0);
    stopTrendTypeLayout->addWidget(stopTrendTypeTrendTypeEnumAbsolute);
    QRadioButton *stopTrendTypeTrendTypeEnumRelative = new QRadioButton(tr("Relative"), stopTrendType);
    stopTrendTypeButtonGroup->addButton(stopTrendTypeTrendTypeEnumRelative, 1);
    stopTrendTypeLayout->addWidget(stopTrendTypeTrendTypeEnumRelative);
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(stopTrendTypeButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(stopTrendTypeChanged(int)));
#else
    connect(stopTrendTypeButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(stopTrendTypeChanged(int)));
#endif
    timeLayout->addWidget(stopTrendType, 2,1);

    stopIndexLabel = new QLabel(tr("Index of last time slice"), central);
    timeLayout->addWidget(stopIndexLabel,3,0);
    stopIndex = new QLineEdit(central);
    connect(stopIndex, SIGNAL(returnPressed()),
            this, SLOT(stopIndexProcessText()));
    timeLayout->addWidget(stopIndex, 3,1);

    // Stride
    strideLabel = new QLabel(tr("Skip rate between time slices"), central);
    timeLayout->addWidget(strideLabel,4,0);
    stride = new QLineEdit(central);
    connect(stride, SIGNAL(returnPressed()),
            this, SLOT(strideProcessText()));
    timeLayout->addWidget(stride, 4,1);


    // Statistics
    statisticGroup = new QGroupBox(central);
    statisticGroup->setTitle(tr("Statistic Type"));
    topLayout->addWidget(statisticGroup);

    QGridLayout *statisticLayout = new QGridLayout(statisticGroup);
    statisticLayout->setContentsMargins(5,5,5,5);
    statisticLayout->setSpacing(10);


    statisticTypeButtonGroup = new QButtonGroup(central);

    QRadioButton *r0 = new QRadioButton(tr("Sum"), central);
    statisticTypeButtonGroup->addButton(r0, StatisticalTrendsAttributes::Sum);
    statisticLayout->addWidget(r0, 0, 0);

    QRadioButton *r1 = new QRadioButton(tr("Mean"), central);
    statisticTypeButtonGroup->addButton(r1, StatisticalTrendsAttributes::Mean);
    statisticLayout->addWidget(r1, 0, 1);

    QRadioButton *r2 = new QRadioButton(tr("Variance"), central);
    statisticTypeButtonGroup->addButton(r2, StatisticalTrendsAttributes::Variance);
    statisticLayout->addWidget(r2, 0, 2);

    QRadioButton *r3 = new QRadioButton(tr("Slope"), central);
    statisticTypeButtonGroup->addButton(r3, StatisticalTrendsAttributes::Slope);
    statisticLayout->addWidget(r3, 1, 0);

    QRadioButton *r4 = new QRadioButton(tr("Residuals"), central);
    statisticTypeButtonGroup->addButton(r4, StatisticalTrendsAttributes::Residuals);
    statisticLayout->addWidget(r4, 1, 1);

    QRadioButton *r5 = new QRadioButton(tr("Std. Dev."), central);
    statisticTypeButtonGroup->addButton(r5, StatisticalTrendsAttributes::StandardDeviation);
    statisticLayout->addWidget(r5, 1, 2);

    r1->setChecked(true);

#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(statisticTypeButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(statisticTypeChanged(int)));
#else
    connect(statisticTypeButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(statisticTypeChanged(int)));
#endif


    // Trend axis
    trendAxisGroup = new QGroupBox(central);
    trendAxisGroup->setTitle(tr("Trend axis"));
    topLayout->addWidget(trendAxisGroup);

    QGridLayout *trendAxisLayout = new QGridLayout(trendAxisGroup);
    trendAxisLayout->setContentsMargins(5,5,5,5);
    trendAxisLayout->setSpacing(10);

    trendAxisButtonGroup= new QButtonGroup(central);

    QRadioButton *trendAxisStep = new QRadioButton(tr("Step"), central);
    trendAxisButtonGroup->addButton(trendAxisStep,0);
    trendAxisLayout->addWidget(trendAxisStep, 0, 0);

    QRadioButton *trendAxisTime = new QRadioButton(tr("Time"), central);
    trendAxisButtonGroup->addButton(trendAxisTime,1);
    trendAxisLayout->addWidget(trendAxisTime, 0, 1);

    QRadioButton *trendAxisCycle = new QRadioButton(tr("Cycle"), central);
    trendAxisButtonGroup->addButton(trendAxisCycle,2);
    trendAxisLayout->addWidget(trendAxisCycle, 0, 2);

#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
    connect(trendAxisButtonGroup, SIGNAL(buttonClicked(int)),
            this, SLOT(trendAxisChanged(int)));
#else
    connect(trendAxisButtonGroup, SIGNAL(idClicked(int)),
            this, SLOT(trendAxisChanged(int)));
#endif
}


// ****************************************************************************
// Method: QvisStatisticalTrendsWindow::UpdateWindow
//
// Purpose: 
//   Updates the widgets in the window when the subject changes.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisStatisticalTrendsWindow::UpdateWindow(bool doAll)
{
    QString temp;

    for(int i = 0; i < atts->NumAttributes(); ++i)
    {
        if(!doAll)
        {
            if(!atts->IsSelected(i))
            {
                continue;
            }
        }

        switch(i)
        {
          case StatisticalTrendsAttributes::ID_startIndex:
            startIndex->blockSignals(true);
            startIndex->setText(IntToQString(atts->GetStartIndex()));
            startIndex->blockSignals(false);
            break;
          case StatisticalTrendsAttributes::ID_startTrendType:
            startTrendTypeButtonGroup->blockSignals(true);
            if(startTrendTypeButtonGroup->button((int)atts->GetStartTrendType()) != 0)
                startTrendTypeButtonGroup->button((int)atts->GetStartTrendType())->setChecked(true);
            updateStartIndexText();
            startTrendTypeButtonGroup->blockSignals(false);
            break;
          case StatisticalTrendsAttributes::ID_stopIndex:
            stopIndex->blockSignals(true);
            stopIndex->setText(IntToQString(atts->GetStopIndex()));
            stopIndex->blockSignals(false);
            break;
          case StatisticalTrendsAttributes::ID_stopTrendType:
            stopTrendType->blockSignals(true);
            if(stopTrendTypeButtonGroup->button((int)atts->GetStopTrendType()) != 0)
                stopTrendTypeButtonGroup->button((int)atts->GetStopTrendType())->setChecked(true);
            updateStopIndexText();
            stopTrendType->blockSignals(false);
            break;
          case StatisticalTrendsAttributes::ID_stride:
            stride->blockSignals(true);
            stride->setText(IntToQString(atts->GetStride()));
            stride->blockSignals(true);
            break;
         case StatisticalTrendsAttributes::ID_statisticType:
            statisticTypeButtonGroup->blockSignals(true);

            if(statisticTypeButtonGroup->button((int)atts->GetStatisticType()) != 0)
              statisticTypeButtonGroup->button((int)atts->GetStatisticType())->setChecked(true);
            statisticTypeButtonGroup->blockSignals(false);

            statisticGroup->setEnabled( atts->GetVariableSource() == StatisticalTrendsAttributes::Default );

            if( atts->GetStatisticType() == StatisticalTrendsAttributes::Slope ||
                atts->GetStatisticType() == StatisticalTrendsAttributes::Residuals )
              trendAxisGroup->setEnabled( true );
            else
              trendAxisGroup->setEnabled( false );
            break;
         case StatisticalTrendsAttributes::ID_trendAxis:
            trendAxisButtonGroup->blockSignals(true);
            if(trendAxisButtonGroup->button((int)atts->GetTrendAxis()) != 0)
                trendAxisButtonGroup->button((int)atts->GetTrendAxis())->setChecked(true);
            trendAxisButtonGroup->blockSignals(false);
            break;

         case StatisticalTrendsAttributes::ID_variableSource:
           statisticGroup->setEnabled( atts->GetVariableSource() == StatisticalTrendsAttributes::Default );
            break;
        }
    }
}


// ****************************************************************************
// Method: QvisStatisticalTrendsWindow::GetCurrentValues
//
// Purpose: 
//   Gets values from certain widgets and stores them in the subject.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisStatisticalTrendsWindow::GetCurrentValues(int which_widget)
{
    bool doAll = (which_widget == -1);

    // Do startIndex
    if(which_widget == StatisticalTrendsAttributes::ID_startIndex || doAll)
    {
        int val;
        if(LineEditGetInt(startIndex, val))
            atts->SetStartIndex(val);
        else
        {
            ResettingError(tr("Index of first time slice"),
                IntToQString(atts->GetStartIndex()));
            atts->SetStartIndex(atts->GetStartIndex());
        }
    }

    // Do stopIndex
    if(which_widget == StatisticalTrendsAttributes::ID_stopIndex || doAll)
    {
        int val;
        if(LineEditGetInt(stopIndex, val))
            atts->SetStopIndex(val);
        else
        {
            ResettingError(tr("Index of last time slice"),
                IntToQString(atts->GetStopIndex()));
            atts->SetStopIndex(atts->GetStopIndex());
        }
    }

    // Do stride
    if(which_widget == StatisticalTrendsAttributes::ID_stride || doAll)
    {
        int val;
        if(LineEditGetInt(stride, val))
            atts->SetStride(val);
        else
        {
            ResettingError(tr("Skip rate between time slices"),
                IntToQString(atts->GetStride()));
            atts->SetStride(atts->GetStride());
        }
    }
}


//
// Qt Slot functions
//


void
QvisStatisticalTrendsWindow::startIndexProcessText()
{
    GetCurrentValues(StatisticalTrendsAttributes::ID_startIndex);
    Apply();
}

void
QvisStatisticalTrendsWindow::startTrendTypeChanged(int val)
{
    if(val != atts->GetStartTrendType())
    {
        atts->SetStartTrendType(StatisticalTrendsAttributes::TrendTypeEnum(val));
        SetUpdate(false);
        Apply();
    }
    updateStartIndexText();
}

void
QvisStatisticalTrendsWindow::updateStartIndexText()
{
    if( atts->GetStartTrendType() == 0 )
    {
        startIndexLabel->setText(tr("Index of the first time slice"));
    }
    else
    {
        startIndexLabel->setText(tr("Number of slices backwards in time"));
    }
}

void
QvisStatisticalTrendsWindow::stopIndexProcessText()
{
    GetCurrentValues(StatisticalTrendsAttributes::ID_stopIndex);
    Apply();
}


void
QvisStatisticalTrendsWindow::stopTrendTypeChanged(int val)
{
    if(val != atts->GetStopTrendType())
    {
        atts->SetStopTrendType(StatisticalTrendsAttributes::TrendTypeEnum(val));
        SetUpdate(false);
        Apply();
    }
    updateStopIndexText();
}

void
QvisStatisticalTrendsWindow::updateStopIndexText()
{
    if( atts->GetStopTrendType() == 0 )
    {
        stopIndexLabel->setText(tr("Index of the last time slice"));
    }
    else
    {
        stopIndexLabel->setText(tr("Number of slices forward in time"));
    }
}

void
QvisStatisticalTrendsWindow::strideProcessText()
{
    GetCurrentValues(StatisticalTrendsAttributes::ID_stride);
    Apply();
}

void
QvisStatisticalTrendsWindow::statisticTypeChanged(int val)
{
    if(val != atts->GetStatisticType())
    {
        atts->SetStatisticType(StatisticalTrendsAttributes::StatisticTypeEnum(val));
        SetUpdate(true);
        Apply();
    }
}

void
QvisStatisticalTrendsWindow::trendAxisChanged(int val)
{
    if(val != atts->GetTrendAxis())
    {
        atts->SetTrendAxis(StatisticalTrendsAttributes::TrendAxisEnum(val));
        SetUpdate(false);
        Apply();
    }
}
